﻿using System;
using System.Collections.Generic;
using BF.IBLL.BaseSystem;
using BF.IDAL.BaseSystem;
using BF.Infrastructure;
using BF.Model;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Security;
using BF.Membership.BLL;
using BF.Membership.MembershipEF;

namespace BF.BLL.BaseSystem
{
    public class Sys_UserInfoBLL : Isys_UserInfoBLL
    {
        private readonly Isys_UserInfoDAL iDal;
        private readonly Isys_RoleInfoDAL iRoleInfoDal;
        private readonly AspnetRolesBLL rolesBLL = new AspnetRolesBLL();
        private readonly IView_SysUserInfoDAL iDalViewUserInfo;
        private readonly IUnitOfWork<WSJD_BaseFrameworkEntities> uwork;
        public Sys_UserInfoBLL(IUnitOfWork<WSJD_BaseFrameworkEntities> uwork, Isys_UserInfoDAL iDal, Isys_RoleInfoDAL iRoleInfoDal, IView_SysUserInfoDAL iDalViewUserInfo)
        {
            this.iDal = iDal;
            this.iRoleInfoDal = iRoleInfoDal;
            this.iDalViewUserInfo = iDalViewUserInfo;
            this.uwork = uwork;
            //因为安全原因，不记录用户表的修改状况。
            //this.uwork.LogEvent = new LogEventHandler(Sys_LogBLL.WriteLog); 
        }


        #region Isys_UserInfoBLL 成员

        public sys_UserInfo GetModelByloginname(string name)
        {
            return iDal.GetModelByCondition(P => P.sLoginName == name);
        }

        public bool Add(sys_UserInfo entity, List<String> roles, bool isapproved)
        {
            MembershipUser user = System.Web.Security.Membership.CreateUser(entity.sLoginName, entity.sPassword);
            if (!isapproved)
            {
                user.IsApproved = false;
                System.Web.Security.Membership.UpdateUser(user);
            }
            foreach (String role in roles)
            {
                Roles.AddUserToRole(entity.sLoginName, role);
            }
            entity.gUserID = new Guid(user.ProviderUserKey.ToString());
            iDal.Add(entity);
            int count = uwork.Commit();
            return (count > 0);

        }

        public bool Delete(sys_UserInfo entity)
        {
            System.Web.Security.Membership.DeleteUser(entity.sLoginName);
            iDal.Delete(entity);
            int count = uwork.Commit();
            if (count > 0)
                return true;
            else
                return false;
        }

        public bool Delete(System.Linq.Expressions.Expression<Func<Model.sys_UserInfo, bool>> predicate)
        {
            iDal.Delete(predicate);
            int count = uwork.Commit();
            if (count > 0)
                return true;
            else
                return false;
        }

        public List<sys_UserInfo> GetList(
            Expression<Func<Model.sys_UserInfo, bool>> where,
            Expression<Func<sys_UserInfo, object>> orderBy,
            PageModel pageModel,
            bool isAscending)
        {
            return iDal.GetList(where, orderBy, pageModel, true);
        }

        public List<sys_UserInfo> GetList(Expression<Func<sys_UserInfo, bool>> where)
        {
            return iDal.GetList(where);
        }

        public List<sys_UserInfo> GetListByRole(string roleName, Expression<Func<sys_UserInfo, bool>> where)
        {
            List<sys_UserInfo> tmpList = iDal.GetList(where);
            string[] userNames = Roles.GetUsersInRole(roleName);
            return tmpList.Where(P => userNames.Contains(P.sLoginName)).ToList();
        }

        public int GetRowCount(Expression<Func<sys_UserInfo, bool>> where)
        {
            return iDal.GetRowCount(where);
        }

        public sys_UserInfo GetModelByPK(Guid gUserID)
        {
            return iDal.GetModelByCondition(P => P.gUserID == gUserID);
        }

        /// <summary>
        /// 根据角色获取用户ID
        /// </summary>
        /// <param name="roleid"></param>
        /// <returns></returns>
        public List<Guid> GetUserIdByRoles(Guid roleid)
        {

            BF.Membership.DAL.AspnetRolesDAL dal = new Membership.DAL.AspnetRolesDAL();
            List<Guid> userIdList = new List<Guid>();
            foreach (var item in dal.GetUserIdByRoles(roleid))
            {
                userIdList.Add(item.UserId);

            }
            return userIdList;

        }


        /// <summary>
        /// 获取当前不属于当前用户创建的角色
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public string[] GetModifyRoleName(sys_UserInfo entity)
        {
            //获取当前用户所有角色
            List<string> allRoleNames = Roles.GetRolesForUser(entity.sLoginName).ToList();

            //获取当前用户创建的角色
            List<sys_RoleInfo> roleInfoList = iRoleInfoDal.GetList(P => P.gCreateUserId == entity.gUserID);
            List<aspnet_Roles> aspnetRolesList = new List<aspnet_Roles>();
            foreach (var item in roleInfoList)
            {
                aspnet_Roles aspnet_Roles = rolesBLL.GetModel(item.gRoleId);
                if (aspnet_Roles != null)
                {
                    aspnetRolesList.Add(aspnet_Roles);
                }
            }
            //定义可以非用户创建的角色数组
            List<string> noCreateRoles = new List<string>();
            List<string> UserCreateRoles = aspnetRolesList.Select(P => P.RoleName).ToList();
            for (int i = 0; i < allRoleNames.Count; i++)
            {
                if (!UserCreateRoles.Contains(allRoleNames[i]))
                {
                    noCreateRoles.Add(allRoleNames[i]);
                }
            }
            string[] noUserCreateRoles = new string[noCreateRoles.Count];
            for (int i = 0; i < noCreateRoles.Count; i++)
            {
                noUserCreateRoles[i] = noCreateRoles[i];
            }
            return noUserCreateRoles;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="roles">修改设定的角色</param>
        /// <param name="isapproved"></param>
        /// <returns></returns>
        public bool Update(sys_UserInfo entity, List<string> roles, bool isapproved)
        {
            MembershipUser user = System.Web.Security.Membership.GetUser(entity.sLoginName);
            user.IsApproved = isapproved;
            entity.iState = isapproved;

            //已有的角色
            string[] roleNames = Roles.GetRolesForUser(entity.sLoginName);

            //已有角色在修改设定的角色中找不到的需要移除
            foreach (string role in roleNames.Where(item => !roles.Contains(item)))
            {
                Roles.RemoveUserFromRole(entity.sLoginName, role);
            }
            //修改设定的角色在已有角色中找不到的需要新增
            foreach (string role in roles.Where(item => !roleNames.Contains(item)))
            {
                Roles.AddUserToRole(entity.sLoginName, role);
            }

            System.Web.Security.Membership.UpdateUser(user);
            if (!string.IsNullOrEmpty(entity.sPassword))
            {
                string oldPassword = user.ResetPassword();
                user.ChangePassword(oldPassword, entity.sPassword);
            }
            return uwork.Commit() > 0;
        }

        //public bool Update(sys_UserInfo entity, List<String> roles, bool isapproved)
        //{
        //    MembershipUser user = System.Web.Security.Membership.GetUser(entity.sLoginName);
        //    user.IsApproved = isapproved;
        //    entity.iState = isapproved;

        //    string[] roleNames = Roles.GetRolesForUser(entity.sLoginName);
        //    if (roleNames.Length > 0)
        //    {
        //        string[] deleteRoleArray = GetModifyRoleName(entity);
        //        if (deleteRoleArray.Length > 0)
        //        {
        //            Roles.RemoveUserFromRoles(entity.sLoginName, deleteRoleArray);
        //        }
        //    }
        //    foreach (String role in roles)
        //    {
        //        if (roleNames.Where(p => p == role).Count() != 0) { continue; }

        //        Roles.AddUserToRole(entity.sLoginName, role);
        //    }
        //    System.Web.Security.Membership.Updateser(user);
        //    if (!string.IsNullOrEmpty(entity.sPassword))
        //    {
        //        string oldPassword = user.ResetPassword();
        //        user.ChangePassword(oldPassword, entity.sPassword);
        //    }

        //    return uwork.Commit() > 0;
        //}

        public bool Delete(Expression<Func<sys_UserInfo, bool>> predicate, string sLoginName, Guid gUserId)
        {
            System.Web.Security.Membership.DeleteUser(sLoginName);
            iDal.Delete(predicate);
            int count = uwork.Commit();
            if (count > 0)
                return true;
            else
                return false;
        }

        public bool Update()
        {
            return uwork.Commit() > 0;
        }

        public List<Guid> GetUserID()
        {

            return null;
        }
        public bool ChangeState(Guid gUserID, bool iState)
        {
            BF.Membership.MembershipEF.vw_aspnet_UsersInRoles list = new Membership.MembershipEF.vw_aspnet_UsersInRoles();

            sys_UserInfo userInfo = iDal.GetModelByCondition(P => P.gUserID == gUserID);
            userInfo.iState = iState;
            //res_HumanResources human = iHumanDal.GetModelByCondition(Q => Q.gUserID == gUserID);
            //if (human != null)
            //{
            //    //if (iState)
            //    //{
            //    //    human.iFlag = 1;
            //    //}
            //    //else
            //    //{
            //    //    human.iFlag = 0;
            //    //}
            //    human.gUserID = null;
            //}
            MembershipUser user = System.Web.Security.Membership.GetUser(gUserID, false);
            user.IsApproved = iState;
            System.Web.Security.Membership.UpdateUser(user);
            return uwork.Commit() > 0;
        }

        #endregion

        public int GetViewRowCount(Expression<Func<View_SysUserInfo, bool>> where)
        {
            return iDalViewUserInfo.GetRowCount(where);
        }

        public List<View_SysUserInfo> GetViewList(Expression<Func<View_SysUserInfo, bool>> where, Expression<Func<View_SysUserInfo, object>> orderBy, PageModel pageModel, bool isAscending)
        {
            return iDalViewUserInfo.GetList(where, orderBy, pageModel, isAscending);
        }

        public List<View_SysUserInfo> GetViewList(Expression<Func<View_SysUserInfo, bool>> where)
        {
            return iDalViewUserInfo.GetList(where);
        }



        public bool ModifyUserRoles(List<Guid> UserList, List<string> RolesList)
        {
            foreach (Guid gUserId in UserList)
            {
                sys_UserInfo userInfo = iDal.GetModelByCondition(P => P.gUserID == gUserId);
                if (userInfo != null)
                {
                    string[] roleNames = Roles.GetRolesForUser(userInfo.sLoginName);
                    if (roleNames.Length > 0)
                    {
                        string[] deleteRoleArray = GetModifyRoleName(userInfo);
                        Roles.RemoveUserFromRoles(userInfo.sLoginName, deleteRoleArray);
                    }
                    foreach (String role in RolesList)
                    {
                        Roles.AddUserToRole(userInfo.sLoginName, role);
                    }
                }
            }
            return uwork.Commit() > 0;
        }


        public bool VolumeLicensing(List<string> roles, List<string> users)
        {
            bool isTrue = false;
            foreach (var userId in users)
            {
                Guid gUserId = Guid.Parse(userId);
                sys_UserInfo userInfo = iDal.GetModelByCondition(P => P.gUserID == gUserId);
                if (userInfo != null)
                {
                    string[] roleNames = Roles.GetRolesForUser(userInfo.sLoginName);
                    try
                    {
                        foreach (String role in roles)
                        {
                            if (!roleNames.Contains(role))
                            {
                                Roles.AddUserToRole(userInfo.sLoginName, role);
                            }
                        }
                        isTrue = true;
                    }
                    catch
                    {
                        isTrue = false;
                    }
                }
            }
            return isTrue;
        }
    }
}
